<template>
  <view
    class="tn-swipe-action-item"
  >
    <!-- 按钮信息 -->
    <view class="tn-swipe-action-item__options">
      <view
        v-for="(item, index) in options"
        :key="index"
        class="tn-swipe-action-item__option"
        :style="optionStyle(index)"
        @tap.stop="handleOptionButtonClick(index)"
      >
        <view class="tn-swipe-action-item__button" :style="optionButtonStyle(index)">
          <view v-if="item.icon" class="icon" :style="optionIconStyle(index)">
            <tn-icon :icon="item.icon"></tn-icon>
          </view>
          <view v-if="item.text" class="text tn-text-ellipsis-1">
            {{ item.text }}
          </view>
        </view>
      </view>
    </view>

    <!-- 内容 -->
    <!-- #ifdef APP-VUE || MP-WEIXIN || MP-QQ || H5 -->
    <view
      class="tn-swipe-action-item__content"
      :style="conetntSwipeStyle"
      @touchstart="touchStart"
      @touchmove="touchMove"
      @touchend="touchEnd"
    >
      <slot></slot>
    </view>
    <!-- #endif -->
  </view>
</template>

<script lang="ts" setup>
import { 
  swipeActionItemProps, 
  SwipeOptionData, 
  SwipeActionItemContect, 
  swipeActionContextKey 
} from '../../../types/tn-swipe-action'
import useSwipeActionItemTouch from '../lib/useSwipeActionItemTouch'
import { 
  inject, 
  computed, 
  ref, 
  CSSProperties, 
  getCurrentInstance, 
  ComponentInternalInstance, 
  onMounted, 
  watch, 
  onBeforeMount, 
  onBeforeUnmount, 
  nextTick 
} from 'vue'
import { uuid, handleValueWithUnit } from '../../../utils'
import TnIcon from '../../tn-icon/src/Icon.vue'

const props = defineProps(swipeActionItemProps)

// 组件id
const id: string = uuid()
const instance = getCurrentInstance() as ComponentInternalInstance
const context: SwipeActionItemContect = {
  id: id,
  name: props.name
}
// 父组件
const swipeAction = inject(swipeActionContextKey, undefined)

// option数据
const options = ref<SwipeOptionData[]>(props?.options)

// option选项样式
const optionStyle = computed<(index: number) => CSSProperties>(() => {
  return (index: number) => {
    let style: CSSProperties = {}
    const option = options.value[index]
    if (option?.borderRadius) style.alignItems = 'center'
    return Object.assign(style, buttonsSwipeStyle.value[index] || {})
  }
})
// option-button样式
const optionButtonStyle = computed<(index: number) => CSSProperties>(() => {
  return (index: number) => {
    let style: CSSProperties = {}
    const option = options.value[index]
    if (option?.bgColor) style.backgroundColor = option.bgColor
    if (option?.color) style.color = option.color
    if (option?.borderRadius) {
      style.borderRadius = option.borderRadius
      style.padding = '0 30rpx'
    }
    if (option?.fontSize) style.fontSize = option.fontSize
    return Object.assign(style, option?.customStyle || {})
  }
})
// option-icon样式
const optionIconStyle = computed<(index: number) => CSSProperties>(() => {
  return (index: number) => {
    let style: CSSProperties = {}
    const option = options.value[index]
    if (option?.iconSize) style.fontSize = handleValueWithUnit(option.iconSize)
    if (option?.text) style.marginRight = '4rpx'
    return style
  }
})

// 判断是否打开显示选项
const isActive = computed<boolean>(() => {
  return swipeAction?.activeName.value.includes(id) || false
})
watch(isActive, (value: boolean) => {
  updateStatus(value)
})

// 处理item点击事件
const handleItemClick = () => {
  swipeAction?.handleItemClick('item', id)
}
// 处理optionsButton点击事件
const handleOptionButtonClick = (index: number) => {
  // console.log(index);
  if (props?.autoClose) {
    swipeAction?.handleItemSwipe('normal', id)
  }
  swipeAction?.handleItemClick('button', id, index)
}
// 关闭其他item
const handleCloseOther = () => {
  swipeAction?.handleItemSwipe('close', id)
}
// 设置item滑动状态
const setSwipeItemStatus = () => {
  swipeAction?.handleItemSwipe('normal', id)
}

// 触摸事件
const {
  conetntSwipeStyle,
  buttonsSwipeStyle,
  updatePropsData,
  updateButtonsRectData,
  updateStatus,
  touchStart,
  touchMove,
  touchEnd
} = useSwipeActionItemTouch(handleItemClick, handleCloseOther, setSwipeItemStatus)

// 按钮选项相关数据
const data: {
  buttons: { width: number }[],
  disabled: boolean,
  threshold: number,
  duration: number
} = {
  buttons: [],
  disabled: false,
  threshold: 20,
  duration: 200
}
// 初始化按钮信息
let initButtonCount = 0
const initButtonsInfo = () => {
  const query: UniApp.SelectorQuery = uni.createSelectorQuery().in(instance)
  query.selectAll('.tn-swipe-action-item__option').boundingClientRect((rect: any) => {
    if (!rect) {
      if (initButtonCount > 10) {
        console.error('[tn-swipe-action]获取options按钮信息失败')
        return
      }
      setTimeout(() => {
        initButtonsInfo()
        initButtonCount++
      }, 50);
      return
    }

    initButtonCount = 0
    updatePropsData({
      disabled: props?.disabled || false,
      threshold: props.threshold !== 'undefined' ? Number(props.threshold) : 50,
      duration: props.duration !== 'undefined' ? Number(props.duration) : 200
    })
    updateButtonsRectData((rect as UniApp.NodeInfo[]).map((node) => {
      return {
        width: node.width || 0
      }
    }))
  }).exec()
}
// 由于wxs无法读取外部状态数据，所以当配置发生变化时重新初始化数据
watch(() => {
  return [props.disabled, props.autoClose, props.threshold, props.duration, props.options]
}, () => {
  initButtonsInfo()
})

onMounted(() => {
  nextTick(() => {
    setTimeout(() => {
      initButtonsInfo()
    }, 50);
  })
  
  swipeAction?.addField(context)
})

onBeforeUnmount(() => {
  swipeAction?.removeField(context)
})
</script>

<style lang="scss" scoped>
@import '../../../theme.scss';

.tn-swipe-action-item {
  position: relative;
  overflow: hidden;
  /* #ifndef APP-NVUE || MP-WEIXIN */
  // touch-action: none;
  /* #endif */

  &__content {
    background-color: #FFFFFF;
    transform: translateX(0px);
  }

  &__options {
    display: flex;
    flex-direction: row;
    align-items: center;
    position: absolute;
    height: 100%;
    top: 0;
    bottom: 0;
    right: 0;
  }

  &__option {
    height: 100%;
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: center;
    overflow: hidden;
  }

  &__button {
    height: 100%;
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: center;
    padding: 0 30rpx;
    overflow: hidden;
    border-radius: 0rpx;
    background-color: $tn-main-color;
    color: #FFFFFF;

    .icon {
      display: flex;
      flex-direction: row;
      align-items: center;
    }

    .text {
      display: flex;
      flex-direction: row;
      align-items: center;
      justify-content: center;
      text-align: center;
      color: inherit;
    }
  }
}
</style>
